package fr.umlv.android.boggle.model;

import java.util.ArrayList;
import java.util.List;

import fr.umlv.android.boggle.listener.GameListener;
import fr.umlv.android.boggle.listener.LetterEvent;
import fr.umlv.android.boggle.listener.LetterListener;
import fr.umlv.android.boggle.listener.WordFoundListener;

public abstract class AbstractBoggleModel implements BoggleModel {
	private List<LetterListener> letterListeners = new ArrayList<LetterListener>();
	private List<WordFoundListener> wordFoundListeners = new ArrayList<WordFoundListener>();
	private List<GameListener> gameListeners = new ArrayList<GameListener>();
	private boolean firingLetter = false;
	private boolean firingWordFound = false ;
	private boolean firingGame = false;

	@Override
	public void addLetterListener(LetterListener letterListener) {
		letterListeners.add(letterListener);
	}
	
	@Override
	public void removeLetterListener(LetterListener letterListener) {
		if(firingLetter)
			throw new IllegalStateException("Cannot remove LetterListeners while fire... is using them");
		letterListeners.remove(letterListener);
	}
	

	protected void fireLetterChanged(Letter letter, int eventType) {
		LetterEvent event = new LetterEvent(letter, eventType);
		try {
			firingLetter = true;
			for(LetterListener listener : letterListeners) {
				listener.letterChanged(event);
			}
		} finally {
			firingLetter = false;
		}
	}

	@Override
	public void addWordFoundListener(WordFoundListener wordFoundListener) {
		wordFoundListeners.add(wordFoundListener);
	}
	
	@Override
	public void removeWordFoundListener(WordFoundListener wordFoundListener) {
		if(firingWordFound)
			throw new IllegalStateException("Cannot remove WordFoundListeners while fire... is using them");
		wordFoundListeners.remove(wordFoundListener);
	}
	
	protected void fireWordFound(String word) {
		try {
			firingWordFound = true;
			for(WordFoundListener listener : wordFoundListeners) {
				listener.newWordFound(word);
			}
		} finally {
			firingWordFound = false;
		}
	}
	
	@Override
	public void addGameListener(GameListener gameListener) {
		gameListeners.add(gameListener);
	}
	
	@Override
	public void removeGameListener(GameListener gameListener) {
		if(firingGame)
			throw new IllegalStateException("Cannot remove GameListeners while fire... is using them");
		gameListeners.remove(gameListener);
	}
	
	protected void fireGameStarted() {
		try {
			firingGame = true;
			for(GameListener listener : gameListeners) {
				listener.gameStarted();
			}
		} finally {
			firingGame = false;
		}
	}
}
